/*
 * iVprog
 * 
 */

package edu.cmu.cs.stage3.swing;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.WindowConstants;

import edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool;

// class: begin
abstract class ReturnValueTracker {

 private javax.swing.JDialog m_dialog;
 private int m_returnValue;

 private java.awt.event.WindowListener m_windowListener = new java.awt.event.WindowAdapter () {
  //Rem @Override
  public void windowClosing (java.awt.event.WindowEvent e) {
   // DialogManager.closing = true;// doesn't working...
   // System.out.println("\n\n===========================\nDialogManager.java: class ReturnValueTracker: windowClosing(java.awt.event.WindowEvent): "+e);
   ReturnValueTracker.this.onWindowClosing(e);
   }
  };

 protected abstract void onWindowClosing(java.awt.event.WindowEvent e);

 public ReturnValueTracker (javax.swing.JDialog dialog, int initialReturnValue) {
  m_dialog = dialog;
  m_returnValue = initialReturnValue;
  m_dialog.addWindowListener(m_windowListener);
  }

 public void setReturnValue (int returnValue) {
  m_returnValue = returnValue;
  }

 public int getReturnValue () {
  return m_returnValue;
  }

 protected javax.swing.JDialog getDialog () {
  return m_dialog;
  }

 public void removeListeners () {
  m_dialog.removeWindowListener(m_windowListener);
  }
 } // abstract class ReturnValueTracker
// class: end 


// class: begin
public class DialogManager {

 private static java.util.Stack s_stack = new java.util.Stack();

 //L Ainda nao usado
 private static Object objFather = null; //L edu.cmu.cs.stage3.alice.core.question.ask.AskUserForNumber - keeps the component father : in order to interrumpt execution if cancel or "closing"
 // To keep component (father of this) 'AuthoringTool' or others ('DeleteContentPane, TempColorPicker, DragFromComponent')
 private static java.util.Stack stackFathers = new java.util.Stack();
 private static Object getDialogStack () { try{ if (stackFathers!=null) return stackFathers.peek(); else return null; }catch(Exception e){return null;} }
 private static void pushDialogStack (Object obj) { try{ if (stackFathers==null) stackFathers = new java.util.Stack(); stackFathers.push(obj); }catch(Exception e){} }
 private static void popDialogStack (Object obj) { try{ if (stackFathers!=null) stackFathers.pop(); }catch(Exception e){} }
 private static javax.swing.JDialog s_dialogManager = null; //L in order to dispose in 'showNumericDialog(...)'

 // doesn't working...
 // A trick to avoid 'edu.cmu.cs.stage3.alice.core.question.ask.AskUserForNumber.getValue()' to calculate an empty number
 // protected static boolean closing = false;
 // public static boolean getClosing () { return closing; }

 // Create 'javax.swing.JDialog' to the main frame of execution
 private static javax.swing.JDialog createModalDialog (String title) {
  java.awt.Component parent;
  try {
   parent = (java.awt.Component) s_stack.peek();
  } catch (java.util.EmptyStackException ese) {
   parent = new java.awt.Frame("empty stack");
   parent.setVisible(true);
   }
  javax.swing.JDialog dialog;
  if (parent instanceof java.awt.Dialog) {
   dialog = new javax.swing.JDialog((java.awt.Dialog) parent, title, true);
  } else {
   dialog = new javax.swing.JDialog((java.awt.Frame) parent, title, true);
   }
  dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
  // System.out.println("\n\n\nDialogManager.java: createModalDialog("+title+")");
  return dialog;
  }

 static int cont=0;
 private static void showModalDialog (javax.swing.JDialog dialog, boolean requiresSetLocationRelativeToOwner) {
  cont++;
  Object obj = getDialogStack(); //L to check if it is from 'AuthoringTool'
  if (dialog.isModal()) {
   //L initiate runnable  'edu.cmu.cs.stage3.scheduler.AbstractScheduler varScheduler' in 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool'
   if (obj instanceof edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool) { // to check if it is from 'AuthoringTool'
      AuthoringTool.getInstance().startScheduler();
      System.out.println("DialogManager.java: showModalDialog(...): start - schedulerThread.isAlive="+AuthoringTool.getInstance().isAlive());
      }
   else System.out.println("DialogManager.java: showModalDialog(...): nao start - schedulerThread.isAlive="+AuthoringTool.getInstance().isAlive());

   if (requiresSetLocationRelativeToOwner) {
    dialog.setLocationRelativeTo(dialog.getOwner());
    }
   //- System.out.println("DialogManager.java: showDialog(javax.swing.JDialog,boolean): push dialog");
   s_stack.push(dialog);
   try {
    dialog.setVisible(true);
   } finally {
    //- System.out.println("DialogManager.java: showDialog(javax.swing.JDialog,boolean): pop dialog");
    s_stack.pop();
    }
  } else {
   System.err.println("Error: DialogManager.java: showModalDialog(...): RuntimeException");
   throw new RuntimeException("DialogManager only handles *modal* dialogs");
   }
  //- System.out.println("DialogManager.java: showDialog(javax.swing.JDialog,boolean): final");
  } //  private static void showModalDialog(javax.swing.JDialog dialog, boolean requiresSetLocationRelativeToOwner)

 private static void showModalDialog (javax.swing.JDialog dialog) {
  showModalDialog(dialog, true);
  }

 public static void initialize (java.awt.Window root) {
  s_stack.clear();
  s_stack.push(root);
  }

 // Initial method here
 // src/edu/cmu/cs/stage3/alice/authoringtool/AuthoringTool.java: void play (): troquei 'DialogManager.showDialog(this,renderContentPane)'
 // src/edu/cmu/cs/stage3/alice/authoringtool/dialog/DeleteContentPane.java: static void showDeleteDialog(edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable deleteRunnable, AuthoringTool authoringTool)
 // src/edu/cmu/cs/stage3/alice/authoringtool/editors/compositeeditor/TempColorPicker.java: private class TileColorPicker extends javax.swing.JPanel - public void actionPerformed(java.awt.event.ActionEvent ev): newColor = DialogManager.showDialog(colorChooser, "Pick color for "+...
 // src/edu/cmu/cs/stage3/alice/authoringtool/DragFromComponent.java: private void guiInit (): 'DialogManager.showDialog(newResponseContentPane)' e 'DialogManager.showDialog(newQuestionContentPane)'
 public static int showDialog (Object obj, ContentPane contentPane) {

  pushDialogStack(obj); // push 'AuthoringTool' or others to 'stackFathers'

  javax.swing.JDialog dialog = createModalDialog(contentPane.getTitle());
  dialog.getContentPane().setLayout(new java.awt.BorderLayout());
  dialog.getContentPane().add(contentPane, java.awt.BorderLayout.CENTER);
  dialog.pack();

  class ContentPaneReturnValueTracker extends ReturnValueTracker {
   private ContentPane m_contentPane;
   private java.awt.event.ActionListener m_okListener = new java.awt.event.ActionListener() {
    public void actionPerformed (java.awt.event.ActionEvent e) {
     // System.out.println("\n\nDialogManager.java: class ContentPaneReturnValueTracker: actionPerformed("+e+") ========================");
     if (m_contentPane.isReadyToDispose(ContentPane.OK_OPTION)) {
      setReturnValue(ContentPane.OK_OPTION);
      getDialog().dispose();
      }
     }
    }; // java.awt.event.ActionListener m_okListener

   private java.awt.event.ActionListener m_cancelListener = new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
     // System.out.println("\n\nDialogManager.java: class ContentPaneReturnValueTracker: cancel actionPerformed("+e+") ========================");
     if (m_contentPane.isReadyToDispose(ContentPane.CANCEL_OPTION)) {
      setReturnValue(ContentPane.CANCEL_OPTION);
      getDialog().dispose();
      }
     }
    }; // java.awt.event.ActionListener m_cancelListener

   public ContentPaneReturnValueTracker (javax.swing.JDialog dialog, ContentPane contentPane) {
    super(dialog, ContentPane.CANCEL_OPTION);
    m_contentPane = contentPane;
    m_contentPane.addOKActionListener(m_okListener); // edu.cmu.cs.stage3.swing.DialogManager
    m_contentPane.addCancelActionListener(m_cancelListener); // edu.cmu.cs.stage3.swing.DialogManager (not the same instance of 'm_okListener')
    // System.out.println("\n\nDialogManager.java: ContentPaneReturnValueTracker(...): cancel: "+(m_contentPane.isReadyToDispose(ContentPane.CANCEL_OPTION)));
    // System.out.println("\n\nDialogManager.java: ContentPaneReturnValueTracker(...): m_okListener="+m_okListener+" m_cancelListener="+m_cancelListener);
    } // in 'class ContentPaneReturnValueTracker extends ReturnValueTracker'

   //Rem @Override
   // Close the main simulation window
   protected void onWindowClosing (java.awt.event.WindowEvent e) { // class ContentPaneReturnValueTracker extends ReturnValueTracker
    // System.out.println("\n\n===========================\nDialogManager.java: class ContentPaneReturnValueTracker: onWindowClosing(java.awt.event.WindowEvent): "+m_contentPane.isReadyToDispose(ContentPane.CANCEL_OPTION));
    if (m_contentPane.isReadyToDispose(ContentPane.CANCEL_OPTION)) {
     // DialogManager.closing = true; // doesn't working...
     setReturnValue(ContentPane.CANCEL_OPTION);
     m_contentPane.handleDispose();
     }
    }

   //Rem @Override
   public void removeListeners () {
    super.removeListeners();
    m_contentPane.removeOKActionListener(m_okListener);
    m_contentPane.removeCancelActionListener(m_cancelListener);
    }
   } // class ContentPaneReturnValueTracker extends ReturnValueTracker

  DialogManager.s_dialogManager = dialog; //L in order to dispose in 'showNumericDialog(...)'

  ContentPaneReturnValueTracker returnValueTracker = new ContentPaneReturnValueTracker(dialog, contentPane);
  // returnValueTracker = new ContentPaneReturnValueTracker(dialog, contentPane); //L erro

  // prepair content in the window
  contentPane.preDialogShow(dialog); // associado com - src/edu/cmu/cs/stage3/progress/ProgressPane.java?

  //- System.out.println("DialogManager.java: showDialog(...): inicio");
  showModalDialog(dialog, false); // showModalDialog(...) does 'obj = getDialogStack();'

  // 
  contentPane.postDialogShow(dialog);

  // Stop 'edu.cmu.cs.stage3.scheduler.AbstractScheduler schedulerThread' in 'edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool'
  if (obj instanceof edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool) AuthoringTool.getInstance().stopScheduler(); //L

  returnValueTracker.removeListeners();

  popDialogStack(obj); //L

  //- System.out.println("DialogManager.java: showDialog(...): fim");
  return returnValueTracker.getReturnValue();
  } // public static int showDialog(Object obj, ContentPane contentPane)

 public static java.awt.Color showDialog (final javax.swing.JColorChooser colorChooser, String title, java.awt.Color initialColor) {

  // class: begin
  class ColorTracker implements java.awt.event.ActionListener {
   java.awt.Color m_color = null;
   public void actionPerformed (java.awt.event.ActionEvent e) {
    m_color = colorChooser.getColor();
    }
   public java.awt.Color getColor () {
    return m_color;
    }
   } // class: end

  ColorTracker colorTracker = new ColorTracker();
  java.awt.Component parent = (java.awt.Component) s_stack.peek();
  javax.swing.JDialog dialog = javax.swing.JColorChooser.createDialog(parent, title, true, colorChooser, colorTracker, null);
  showModalDialog(dialog);
  return colorTracker.getColor();
  } // public static java.awt.Color showDialog(final javax.swing.JColorChooser colorChooser, String title, java.awt.Color initialColor)

 public static int showDialog (boolean open, javax.swing.JFileChooser fileChooser, String approveButtonText) {
  if (approveButtonText != null) {
   fileChooser.setApproveButtonText(approveButtonText);
   fileChooser.setDialogType(javax.swing.JFileChooser.CUSTOM_DIALOG);
   }
  String title = fileChooser.getUI().getDialogTitle(fileChooser);
  fileChooser.getAccessibleContext().setAccessibleDescription(title);

  javax.swing.JDialog dialog = createModalDialog(title);

  java.awt.Container contentPane = dialog.getContentPane();
  contentPane.setLayout(new java.awt.BorderLayout());
  contentPane.add(fileChooser, java.awt.BorderLayout.CENTER);

  dialog.pack();

  // class: begin
  class FileChooserReturnValueTracker extends ReturnValueTracker {
   private javax.swing.JFileChooser m_fileChooser;

   //
   private java.awt.event.ActionListener m_actionListener = new java.awt.event.ActionListener() {
    public void actionPerformed (java.awt.event.ActionEvent e) {
     String command = e.getActionCommand();
     // System.out.println("\n\nDialogManager.java: class FileChooserReturnValueTracker: m_actionListener: "+command);
     if (command.equals(javax.swing.JFileChooser.APPROVE_SELECTION)) {
      setReturnValue(javax.swing.JFileChooser.APPROVE_OPTION);
     } else if (command.equals(javax.swing.JFileChooser.CANCEL_SELECTION)) {
      setReturnValue(javax.swing.JFileChooser.CANCEL_OPTION);
      }
     getDialog().dispose();
     }
    };

   public FileChooserReturnValueTracker (javax.swing.JDialog dialog, javax.swing.JFileChooser fileChooser) {
    super(dialog, javax.swing.JFileChooser.CANCEL_OPTION);// javax.swing.JFileChooser.ERROR_OPTION );
    m_fileChooser = fileChooser;
    m_fileChooser.addActionListener(m_actionListener);
    }

   //Rem @Override
   protected void onWindowClosing (java.awt.event.WindowEvent e) { // file dialog
    // DialogManager.closing = true; // doesn't working...
    // System.out.println("\n\n===========================\nDialogManager.java: class FileChooserReturnValueTracker: onWindowClosing("+e+")");
    setReturnValue(javax.swing.JFileChooser.CANCEL_OPTION);
    getDialog().dispose();
    }

   //Rem @Override
   public void removeListeners () {
    super.removeListeners();
    m_fileChooser.removeActionListener(m_actionListener);
    }

   } // class FileChooserReturnValueTracker extends ReturnValueTracker
   // class: end

  FileChooserReturnValueTracker returnValueTracker = new FileChooserReturnValueTracker(dialog, fileChooser);

  fileChooser.rescanCurrentDirectory();

  showModalDialog(dialog);

  returnValueTracker.removeListeners();

  return returnValueTracker.getReturnValue();
  } // static int showDialog(boolean open, javax.swing.JFileChooser fileChooser, String approveButtonText)

 public static int showOpenDialog (javax.swing.JFileChooser fileChooser) {
  fileChooser.setDialogType(javax.swing.JFileChooser.OPEN_DIALOG);
  return showDialog(true, fileChooser, null); //L showDialog(fileChooser, null);
  }

 public static int showSaveDialog (javax.swing.JFileChooser fileChooser) {
  fileChooser.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
  return showDialog(false, fileChooser, null); //L showDialog(fileChooser, null);
  }

 private static String getUIManagerString (Object key) {
  // todo: java1.4
  // java.awt.Component component = (java.awt.Component)s_stack.peek();
  // return javax.swing.UIManager.getString( key, component.getLocale() );
  // System.out.println("DialogManager.java: getUIManagerString(...): key="+key);
  if (key.equals("OptionPane.inputDialogTitle")) {
   return "Input";
  } else if (key.equals("OptionPane.messageDialogTitle")) {
   return "Message";
  } else if (key.equals("OptionPane.titleText")) {
   return "Select an Option";
   }
  return "";
  }

 public static String showInputDialog (Object message, String title, int messageType) {
  return (String) showInputDialog(message, title, messageType, null, null, null, false);
  }

 public static String showNumericDialog (edu.cmu.cs.stage3.alice.core.question.ask.AskUserForNumber aufn, Object message, String title, int messageType) {
  // doesn't working...: closing = false; // a trick to avoid 'edu.cmu.cs.stage3.alice.core.question.ask.AskUserForNumber.getValue()' to calculate an empty number
  DialogManager.objFather = aufn; //L keeps the component father : in order to interrumpt execution if cancel or "closing"
  pushDialogStack(aufn); //L push the father - remover
  // System.out.println("\n\n\nDialogManager.java: showInputDialog("+message+","+title+"...): ===============================");
  String strReturn = (String) showInputDialog(message, title, messageType, null, null, null, true);

  if (strReturn==null)  {// implies that used 'cancel' button or the window was closed in 'javax.swing.JOptionPane'
     System.out.println("\nDialogManager.java: showInputDialog("+message+","+title+"...): stop ");
     // try { String str=""; System.out.println(str.charAt(3)); } catch (Exception e) {e.printStackTrace();}
     // at edu.cmu.cs.stage3.alice.core.response.DoInOrder$RuntimeDoInOrder.update(DoInOrder.java:135): quitTimeRemaining()
     AuthoringTool.getInstance().getWorldClock().stop();
     // DialogManager.s_dialogManager.dispose(); // returnValueTracker.setReturnValue(ContentPane.CANCEL_OPTION);
     // returnValueTracker.m_contentPane.handleDispose(); // class ContentPaneReturnValueTracker extends ReturnValueTracker
     }

  popDialogStack(aufn); //L pop the father - remover
  return strReturn;
  // return (String) showInputDialog(message, title, messageType, null, null, null, true);
  }

 //static int cont=0;
 public static Object showInputDialog (Object message, String title, int messageType, Icon icon, Object[] selectionValues, Object initialSelectionValue, boolean isNumber) {

  JOptionPane jOptionPane = new JOptionPane(message, messageType, JOptionPane.OK_CANCEL_OPTION, icon, null, null); // javax.swing.JOptionPane
  // System.out.println("DialogManager.java: showInputDialog(...): "+title+": "+message);
  // if (cont==0) try { String str=""; if (cont==0) System.out.println(str.charAt(3)); } catch (Exception e) {e.printStackTrace();} cont++;

  jOptionPane.setWantsInput(true);
  jOptionPane.setSelectionValues(selectionValues);
  jOptionPane.setInitialSelectionValue(initialSelectionValue);

  if (isNumber) {
   addTextFieldListener(jOptionPane.getComponents());
   }

  java.awt.Component parent = (java.awt.Component) s_stack.peek();
  jOptionPane.setComponentOrientation(parent.getComponentOrientation());

  javax.swing.JDialog dialog = jOptionPane.createDialog(parent, title);

  jOptionPane.selectInitialValue();

  showModalDialog(dialog);

  Object value = jOptionPane.getInputValue();

  if (value == javax.swing.JOptionPane.UNINITIALIZED_VALUE) {
   return null;
  } else {
   return value;
   }
  } // static String showNumericDialog(edu.cmu.cs.stage3.alice.core.question.ask.AskUserForNumber aufn, Object message, String title, int messageType)

 private static void addTextFieldListener (Component[] components) {
  if (components == null || components.length < 1) {
   return;
   }
  //LOB for (Component component : components)
  int _tam = components!=null ? components.length : 0;
  for (int _i=0; _i<_tam; _i++) { //L
   if (components[_i] instanceof JPanel) { //L (component instanceof JPanel)
    JPanel panel =  (JPanel)components[_i]; //L (JPanel)component;
    addTextFieldListener(panel.getComponents());
   } else if (components[_i] instanceof JTextField) { //L (component instanceof JTextField)
    components[_i].addKeyListener(new KeyAdapter() { //L component.addKeyListener(new KeyAdapter()
     public void keyTyped(KeyEvent e) {
      char c = e.getKeyChar();
      if (!(Character.isDigit(c) || (c == '-') || (c == '.') || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE))) {
       e.consume();
       }
      } // void keyTyped(KeyEvent e)
     });
    } // else if (components[_i] instanceof JTextField)
   } // for (int _i=0; _i<_tam; _i++)
  } // static void addTextFieldListener (Component[] components)

 public static void showMessageDialog (Object message) {
  showMessageDialog(message, getUIManagerString("OptionPane.messageDialogTitle"), javax.swing.JOptionPane.INFORMATION_MESSAGE);
  }

 public static void showMessageDialog (Object message, String title, int messageType) {
  showMessageDialog(message, title, messageType, null);
  }

 public static void showMessageDialog (Object message, String title, int messageType, javax.swing.Icon icon) {
  showOptionDialog(message, title, javax.swing.JOptionPane.DEFAULT_OPTION, messageType, icon, null, null);
  }

 public static int showConfirmDialog (Object message) {
  return showConfirmDialog(message, getUIManagerString("OptionPane.titleText"), javax.swing.JOptionPane.YES_NO_CANCEL_OPTION);
  }

 public static int showConfirmDialog (Object message, String title, int optionType) {
  return showConfirmDialog(message, title, optionType, javax.swing.JOptionPane.QUESTION_MESSAGE);
  }

 public static int showConfirmDialog (Object message, String title, int optionType, int messageType) {
  return showConfirmDialog(message, title, optionType, messageType, null);
  }

 public static int showConfirmDialog (Object message, String title, int optionType, int messageType, javax.swing.Icon icon) {
  return showOptionDialog(message, title, optionType, messageType, icon, null, null);
  }

 public static int showOptionDialog (Object message, String title, int optionType, int messageType, javax.swing.Icon icon, Object[] options, Object initialValue) {
  javax.swing.JOptionPane pane = new javax.swing.JOptionPane(message, messageType, optionType, icon, options, initialValue);

  pane.setInitialValue(initialValue);
  java.awt.Component parent = (java.awt.Component) s_stack.peek();
  pane.setComponentOrientation(parent.getComponentOrientation());

  javax.swing.JDialog dialog = pane.createDialog(parent, title);
  pane.selectInitialValue();
  showModalDialog(dialog);

  Object selectedValue = pane.getValue();

  if (selectedValue == null)
   return javax.swing.JOptionPane.CLOSED_OPTION;
  if (options == null) {
   if (selectedValue instanceof Integer)
    return ((Integer) selectedValue).intValue();
   return javax.swing.JOptionPane.CLOSED_OPTION;
   }
  for (int counter = 0, maxCounter = options.length; counter < maxCounter; counter++) {
   if (options[counter].equals(selectedValue))
    return counter;
   }
  return javax.swing.JOptionPane.CLOSED_OPTION;
  } // static int showOptionDialog(Object message,String title,int optionType,int messageType,javax.swing.Icon icon,Object[] options,Object initialValue)

 public static void showTextDialog (String text) {
  JPanel textPanel = new JPanel(new BorderLayout());
  textPanel.setBorder(BorderFactory.createEmptyBorder(15, 25, 15, 25));
  JTextPane textPane = new JTextPane();
  JScrollPane scrollPane = new JScrollPane(textPane);

  textPane.setText(text);
  textPane.setEditable(false);
  textPanel.add(scrollPane);
 
  javax.swing.JDialog dialog = new JDialog(AuthoringTool.getInstance().getJAliceFrame(), true);
  // System.out.println("\n\n\nDialogManager.java: showTextDialog("+text+")");

  dialog.setBounds(0, 0, 800, 500);
  dialog.getContentPane().add(textPanel); //L dialog.add(textPanel); - java.lang.Error: Do not use javax.swing.JDialog.add() use javax.swing.JDialog.getContentPane().add() instead

  showModalDialog(dialog);
  }

 } // public class DialogManager
// class: end
